package edu.mtu.citizenscience.cs.notepad.activity.noteslist.note;

import android.location.Location;
import android.os.Bundle;
import edu.mtu.citizenscience.cs.notepad.NPActivity;
import edu.mtu.citizenscience.cs.notepad.activity.R;
import edu.mtu.citizenscience.cs.notepad.activity.noteslist.EnableGPSDialog;
import edu.mtu.citizenscience.cs.notepad.activity.noteslist.note.location.LocationDialog;
import edu.mtu.citizenscience.cs.notepad.model.ModelNote;
import edu.mtu.citizenscience.cs.notepad.model.note.ModelLocation;
import edu.mtu.citizenscience.cs.utils.exceptions.GPSNotAvailable;
import edu.mtu.citizenscience.cs.utils.gps.CitsciGPS;
import edu.mtu.citizenscience.cs.utils.gps.CitsciGPSRequest;
/**
 * @author Corbin Uselton <corbinu@cwuselto@mtu.edu>
 * @copyright (c) 2012 MichiganTech <http://www.mtu.edu>
 * @since 1.0
 * 
 * Location Activity Responsible for 
 * getting and removing the location for a note
 */
public class LocationActivity extends NPActivity {
	// The model of the note the location gets attached to
	private ModelNote note;
	// object for interacting with GPSService to get the current location
	private CitsciGPS gps = new CitsciGPS();
	// dialog to display when waiting to get the note location
	private LocationDialog locationDialog = new LocationDialog();
	// Dialog which shows message to enable GPS
	private EnableGPSDialog gpsEnableDialog = new EnableGPSDialog();
	
	/**
	 * @since 1.0
	 * 
	 * Handles result from a location request to the GPS service
	 */
	private class LocationRequest implements CitsciGPSRequest {

		/**
		 * Called by the CitsciGPS when it has a location
		 * 
		 * @param location - Location - the current location from the GPS
		 * @return void
		 */
		@Override
		public void locationResult(Location location) 
		{
			// save the new location to the report
			saveLocation(location);
		}
		
	}
	
	/**
	 * Location Activity creation handler
	 * 
	 * @param   savedInstanceState - Bundle - Bundle with launch info
	 * @return	void
	 */
	@Override
	public void onCreate(Bundle savedInstanceState) 
	{
		super.onCreate(savedInstanceState);
		
		this.setContentView(R.layout.activity_location);
		
		// try to get the note id from the intent bundle
		long noteId = this.getIntent().getLongExtra(ModelNote.NOTE_ID, -1);
		
		// check to see if got a note id
		if (noteId > -1)
		{
			// set the note model to the model with the given note id
			this.note = new ModelNote(this, noteId);
		}
		else
		{
			// no note to attach the location to so finish the activity
			this.finish();
		}
		
		// check to see if the note has a location already
		if (this.note.getLocation().getId() > -1)
		{
			// display the notes attached location
			this.displayLocation();
		}
		else
		{
			// no location so hide the display
			this.hideLocation();
		}
	}
	
	/**
	 * Location Activity resume handler
	 * 
	 * @param   void
	 * @return	void
	 */
	@Override
    protected void onResume() 
    {
        super.onResume();

        // check if GPS is not enabled
        if ( ! CitsciGPS.isEnabled(this)) 
        {
        	// show dialog to inform the user that they need to enable the GPS
        	this.gpsEnableDialog.show(this.getSupportFragmentManager(), "dialog");
        }
        else
        {
        	try 
    		{
        		// resume the GPS service connection
    			this.gps.resume(this);
    		} 
    		catch (GPSNotAvailable e) 
    		{
    			// when GPS is not available for resume
    			e.printStackTrace();
    		}
        }
    }
	
	/**
	 * Location Activity pause handler
	 * 
	 * @param   void
	 * @return	void
	 */
	@Override
	protected void onPause() 
	{
		super.onPause();
		
		// pause the gps service connection
		this.gps.pause(this);
	}
	
	/**
	 * Displays the notes location
	 * 
	 * @param   void
	 * @return	void
	 */
	public void displayLocation()
	{
		// set the location text to latitude and longitude
		this.aq.id(R.id.attachmentLocation).text("Latitude: " + this.note.getLocation().getLatitude() + ", Longitude: " + this.note.getLocation().getLatitude()).visible();
		
		// set location button text to remove and attach click handler as removeLocation
		this.aq.id(R.id.attachmentLocationButton).text(R.string.remove_button_label).clicked(this, "removeLocation");
	}
	
	/**
	 * onClick handler for get location
	 * 
	 * @param   void
	 * @return	void
	 */
	public void getLocation()
	{
		// create new GPS location request with LocationRequest as the callback handler
		this.gps.requestLocation(new LocationRequest());
		// show the location dialog to inform the user that the app is currently searching for the location
		this.locationDialog.show(this.getSupportFragmentManager(), "dialog");
	}
	
	/**
	 * onClick handler to cancel button on the location dialog
	 * 
	 * @param   void
	 * @return	void
	 */
	public void cancelClicked()
	{
		this.gps.cancelRequst();
		this.locationDialog.dismiss();
	}
	
	/**
	 * Saves new location to the current note
	 * 
	 * @param   location - Location - the new location from the GPS service
	 * @return	void
	 */
	public void saveLocation(Location location)
	{
		// remove the login dialog as have location
		this.locationDialog.dismiss();
		
		// create a new location model
		ModelLocation locationModel = new ModelLocation(this);
		// attach the latitude and longitude to the new location model
		locationModel.setLatitude(location.getLatitude());
		locationModel.setLongitude(location.getLongitude());
		// save the location to the DB
		locationModel.save();
		
		// set the notes location to the new location model
		this.note.setLocation(locationModel);
		// save the note
		this.note.save();
	}
	
	/**
	 * Remove the notes location
	 * 
	 * @param   void
	 * @return	void
	 */
	public void removeLocation()
	{
		// get the location model from the note model and delete it from the DB
		this.note.getLocation().delete();
		// save the note model
		this.note.save();
		
		// hide the location display as there is no longer a location to display
		this.hideLocation();
	}
	
	/**
	 * Hide the location display
	 * 
	 * @param   void
	 * @return	void
	 */
	public void hideLocation()
	{
		// Remove the attachment location text view from the display
		this.aq.id(R.id.attachmentLocation).gone();
		
		// set the location button text to attach text and set click handler to getLocation
		this.aq.id(R.id.attachmentLocationButton).text(R.string.attach_button_label).clicked(this, "getLocation");
	}

}